/*
 * Copyright (c) $today.year-Now http://www.zxpnet.com All rights reserved.
 */

package com.zxp.common.core.validatecode.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.wf.captcha.base.Captcha;
import com.wf.captcha.utils.CaptchaUtil;
import com.zxp.common.core.constant.module.SecurityConstants;
import com.zxp.common.core.security.properties.SecurityProperties;
import com.zxp.common.core.validatecode.ValidateCodeProperties;
import com.zxp.common.core.validatecode.ValidateCodeServiceI;
import com.zxp.common.core.validatecode.bean.ValidateCode;
import com.zxp.common.core.validatecode.captcha.CaptchaHelper;
import com.zxp.common.core.validatecode.exception.ValidateCodeException;
import com.zxp.common.core.validatecode.sms.SmsSenderApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @author: shollin
 * @date: 2021/7/6/006 11:04
 */
@Slf4j
@RequiredArgsConstructor
public class SmsValidateCodeService implements ValidateCodeServiceI {

    private final SecurityProperties securityProperties;
    private final RedisTemplate<String,Object> redisTemplate;
    private final SmsSenderApi smsSenderApi;

    // 参考： https://www.cnblogs.com/chenmz1995/p/12562328.html
    @Override
    public void sendCode(ServletWebRequest request) throws Exception {

        //生成验证码
        String smsCode = RandomUtil.randomNumbers(securityProperties.getCode().getSms().getLength());
        log.debug("短信验证码："+smsCode);

        //保存验证码
        String phone = request.getParameter(SecurityConstants.PARAM_SMS_PHONE);
        //request.getRequest().getSession().setAttribute("SESSION_PHONE",phone+"_"+ code);
        redisTemplate.opsForValue().set(phone+ SecurityConstants.SMS_LOGIN_CODE_KEY,smsCode,
                securityProperties.getCode().getSms().getExpireIn(),TimeUnit.SECONDS);

        // 记数，防止频繁发送
        String countKey = phone+ SecurityConstants.SMS_LOGIN_COUNT_KEY;
        Object cnt = redisTemplate.opsForValue().get(countKey);
        if(cnt==null){
            redisTemplate.opsForValue().set(countKey,"1",60 * 60 * 24,TimeUnit.SECONDS); // 1天
        }else{
            //redisTemplate.opsForValue().increment(countKey);
        }


        // 第三步：发送验证码
        smsSenderApi.send(phone,smsCode);

    }

    @Override
    public void checkCode(ServletWebRequest request) throws ValidateCodeException {

        String smsCode = request.getParameter(SecurityConstants.PARAM_SMS_CODE);
        String phone = request.getParameter(SecurityConstants.PARAM_SMS_PHONE);

        // 校验验证码
        Object smsCodeRedis = redisTemplate.opsForValue().get(phone+ SecurityConstants.SMS_LOGIN_CODE_KEY);

        if(ObjectUtil.isEmpty(smsCodeRedis)){
            throw new ValidateCodeException("短信验证码不存在或已过期");
        }
        if(StrUtil.isBlank(smsCode)){
            throw new ValidateCodeException("请输入短信验证码");
        }
        if(!smsCode.equalsIgnoreCase(smsCodeRedis.toString())){
            throw new ValidateCodeException("短信验证码不准确");
        }
    }
}
